﻿using com.yoozoo.gta.Gameplay.RTS;
using com.youzu.got.protocol;
using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using XLua;
using Yoozoo.Gameplay.RTS.Proto;
using Yoozoo.Mars.Got;
using Yoozoo.UI.YGUI;

namespace Yoozoo.Gameplay.RTS
{
    public enum HudType
    {
        Troop,
        Monster,
    }
    public abstract class HudBase
    {
        private static bool isDebug = false;
        /// <summary>
        /// 保存部队根节点坐标，每帧通过UpdateFollowPos更新Hud的坐标，避免使用和回池时的SetParent消耗
        /// </summary>
        protected Vector3 parentPos;
        protected MarchEntity MarchEntity;
        public MarchEntity GetMarchEntity
        {
            get
            {
                return MarchEntity;
            }
        }
        protected MarchType MarchType;
        protected TargetCoordinateType MarchTargetType;
        protected EMarchStatus ClientMarchStatus;
        public GameObject Lod0;
        public GameObject Lod1;
        public MarchHudLod0 MarchHudLod0;
        public GameObject NewYearHudLod0;
        protected int MaxRage;
        public HudType HudType;
        public bool IsClientInBattle;
        public string[] HeroIcons = new string[3];
        public long BattleTargetId;
        public bool IsAttackSelf;//被我攻击的人
        public bool IsSelfAttacked;//别人攻击我
        public bool IsSelfAttacking;//我正在攻击
        public MarchEntity target;
        protected Vector3 _localPosition;
        private bool isTweenAlpha = false;
        private float tweenAlphaTime = 0.4f;
        private float targetAlpha;
        private float startAlpha;
        public float currentAlpha;
        public float Alpha = 1;
        private float currentTime;
        protected bool _isBattleStyle = true;//用于拖拽到目标头像，是否为战斗或非战斗的标记
        protected int _marchLodLevel = -1;
        public int MarchLodLevel
        {
            get{
                return _marchLodLevel;
            }
        }

        protected bool showCommanderHead
        {
            get { return GetHeadShowValue(EHeadShowChange.IsHeadVisible); }
        }
        protected abstract void SelfInit();
        protected abstract void InitParentScaleAndPosition();
        protected bool isSelfJoinedBattle => MarchEntity.MarchInfo.Team == 0 || IsAttackSelf || IsSelfAttacked || IsSelfAttacking;

        protected bool isHiding = false;

        //组件
        /// <summary>
        /// 头像
        /// </summary>
        public CommanderHead commanderHead;
        
        /// <summary>
        /// 点赞Tips
        /// </summary>
        public TsanTip tsanTip;
        
        /// <summary>
        /// 展开的详情
        /// </summary>
        protected BaseArmyInfo baseArmyInfo;

        
        /// <summary>
        /// 城防血条
        /// </summary>
        protected GameObject wallHp;
        
        //下面的
        protected enum EHeadFactor
        {
            IsMonster,
            IsNotShowCommanderHead,//不用显示战斗头像的
            IsDefence,
            IsSoldierEmpty,
            IsInBuilding,
            IsAssemblyMember,//参加集结的人
            IsAssemblyLeader,//车头
            IsAssemblyWaiting,//是集结部队 等待
            IsSelected,
            IsForceShow,
            IsBattleStyle,//未知，先保留
            IsAttackSelf,
            IsAttackedBySelf,
            IsInBattle,
            IsCollecting,
            IsEscaping,
            IsTeamSelf,
            IsTeamAlly,
            IsTeamOther,
            IsAid,
            IsBridge,
            IsReturningToNormalStyle,//从拉线状态变回普通状态
            IsDefenceTroop,
            IsWonderNpc,
            IsPoliceOffice,
            IsArena,
            IsPracticeBoss,
            IsExpeditionDeck,
            IsInAllianceBuild,// 驻扎在联盟建筑里面
            IsTruckFighting,
            IsTrainFighting, // 列车战斗
            IsInWonder, // 部队在奇观中
            IsCanShowNewYearHud,// 1.春节活动期间 2.在烟花燃放时间段 3.在烟花燃放范围内有部队
        }

        protected enum EHeadShowChange
        {
            IsBattleState,
            IsHeadVisible,//头像
            IsPlayerNameVisible,//驻扎时部队头顶的名字
            IsBaseInfoVisible,//头像右侧的详情（名字+兵量）
            IsRageVisible,//怒气
            IsShowCommanderHeadPlayerName,//头像下面的名字
            IsBridgeHpVisible,//桥梁血条
            IsNewYearHudVisible,//春节活动燃放烟花Hud
        }
        
        protected class HeadFactorData
        {
            public bool value;
            public List<EHeadShowChange> showChangeType;
            public Action<bool> onValueChange;
            public Action<bool> onValueChangeImmediately;
        }
        
        protected delegate bool HeadShowValueGetter();
        
        protected class HeadShowChangeAction
        {
            public bool isDirty;
            public bool value;
            public Action<bool> onValueChange;
            public HeadShowValueGetter valueGetter;
        }

        private Dictionary<EHeadFactor, HeadFactorData> headFactorToShowMap = new Dictionary<EHeadFactor, HeadFactorData>();

        private Dictionary<EHeadShowChange, HeadShowChangeAction> headShowChangeActionMap =
            new Dictionary<EHeadShowChange, HeadShowChangeAction>();

        private static List<EHeadShowChange> headShowChangePriority = new List<EHeadShowChange>
        {
            EHeadShowChange.IsHeadVisible,
            EHeadShowChange.IsBattleState,
            EHeadShowChange.IsPlayerNameVisible,
            EHeadShowChange.IsBaseInfoVisible,
            EHeadShowChange.IsRageVisible,
            EHeadShowChange.IsShowCommanderHeadPlayerName,
            EHeadShowChange.IsBridgeHpVisible,
            EHeadShowChange.IsNewYearHudVisible,
        };

        private static Dictionary<EHeadShowChange, List<EHeadFactor>> headFactorToShowRelation =
            new Dictionary<EHeadShowChange, List<EHeadFactor>>
            {
                [EHeadShowChange.IsHeadVisible] = new List<EHeadFactor>
                {
                    EHeadFactor.IsDefence,
                    EHeadFactor.IsNotShowCommanderHead,
                    EHeadFactor.IsArena,
                    EHeadFactor.IsMonster,
                    EHeadFactor.IsInBuilding,
                    EHeadFactor.IsAssemblyMember,
                    EHeadFactor.IsAssemblyLeader,
                    EHeadFactor.IsSelected,
                    EHeadFactor.IsForceShow,
                    EHeadFactor.IsTeamSelf,
                    EHeadFactor.IsAttackSelf,
                    EHeadFactor.IsAttackedBySelf,
                    EHeadFactor.IsInBattle,
                    EHeadFactor.IsReturningToNormalStyle,
                    EHeadFactor.IsSoldierEmpty,
                    EHeadFactor.IsBridge,
                    EHeadFactor.IsPracticeBoss,
                    EHeadFactor.IsExpeditionDeck,
                    EHeadFactor.IsInAllianceBuild,
                    EHeadFactor.IsTruckFighting,
                    EHeadFactor.IsTrainFighting,
                    EHeadFactor.IsInWonder,
                },
                [EHeadShowChange.IsBattleState] = new List<EHeadFactor>
                {
                    EHeadFactor.IsInBattle,
                    EHeadFactor.IsCollecting,
                    EHeadFactor.IsEscaping,
                    EHeadFactor.IsInBuilding,
                    EHeadFactor.IsDefenceTroop,
                    EHeadFactor.IsDefence,
                },
                [EHeadShowChange.IsPlayerNameVisible] = new List<EHeadFactor>
                {
                    EHeadFactor.IsInBattle,
                    EHeadFactor.IsCollecting,
                    EHeadFactor.IsEscaping,
                    EHeadFactor.IsSelected,
                    EHeadFactor.IsForceShow,
                    EHeadFactor.IsAid,
                    EHeadFactor.IsInBuilding,
                    EHeadFactor.IsDefence,
                    EHeadFactor.IsAssemblyLeader,
                    EHeadFactor.IsAssemblyMember,
                    EHeadFactor.IsDefenceTroop,
                    EHeadFactor.IsAssemblyWaiting,
                    EHeadFactor.IsArena,
                },
                [EHeadShowChange.IsBaseInfoVisible] = new List<EHeadFactor>
                {
                    EHeadFactor.IsSelected,
                    EHeadFactor.IsArena,
                    EHeadFactor.IsExpeditionDeck,
                    EHeadFactor.IsForceShow,
                    EHeadFactor.IsBattleStyle,
                    EHeadFactor.IsEscaping,
                },
                [EHeadShowChange.IsRageVisible] = new List<EHeadFactor>
                {
                    EHeadFactor.IsInBattle,
                    EHeadFactor.IsTeamSelf,
                    EHeadFactor.IsAttackSelf,
                    EHeadFactor.IsAttackedBySelf,
                },
                [EHeadShowChange.IsShowCommanderHeadPlayerName] = new List<EHeadFactor>
                {
                    EHeadFactor.IsMonster,
                    EHeadFactor.IsInBattle,
                    EHeadFactor.IsSelected,
                },
                [EHeadShowChange.IsBridgeHpVisible] = new List<EHeadFactor>
                {
                    EHeadFactor.IsInBattle,
                    EHeadFactor.IsBridge,
                },
                [EHeadShowChange.IsNewYearHudVisible] = new List<EHeadFactor>
                {
                    EHeadFactor.IsCanShowNewYearHud,
                    EHeadFactor.IsInBattle,
                    EHeadFactor.IsSelected,
                },
            };
        

        private List<HeadShowChangeAction> headShowChangeActions = new List<HeadShowChangeAction>();
        private List<HeadFactorData> headFactorChangedList = new List<HeadFactorData>(5);

        private bool headShowChangeActionInited = false;

        private void OnSelectedChanged(bool isSelected)
        {
            UpdateCommanderHeadScale();
        }

        private void OnIsInBattleChanged(bool isInBattle)
        {
            inBattleStateChangedAction?.Invoke(isInBattle);
            if (!isInBattle)
            {
                ResetHudToNormalStyle();
            }
        }

        private Action<bool> GetFactorChangeActionImmediately(EHeadFactor factor)
        {
            if (factor == EHeadFactor.IsInBattle)
            {
                return OnIsInBattleChanged;;
            }
            return null;
        }
        
        private Action<bool> GetFactorChangeAction(EHeadFactor factor)
        {
            if (factor == EHeadFactor.IsSelected | factor == EHeadFactor.IsForceShow)
            {
                return OnSelectedChanged;
            }

            return null;
        }
        
        /// <summary>
        /// 初始化字典
        /// </summary>
        private void InitHeadShowChangeAction()
        {
            if (headShowChangeActionInited)
            {
                return;
            }

            headShowChangeActionInited = true;
            headShowChangeActionMap.Add(EHeadShowChange.IsHeadVisible,new HeadShowChangeAction
            {
                valueGetter = CommanderHeadVisible,
                onValueChange = OnCommanderHeadVisibleChanged,
            });
            headShowChangeActionMap.Add(EHeadShowChange.IsBattleState,new HeadShowChangeAction
            {
                valueGetter = CommanderHeadInBattleState,
                onValueChange = OnCommanderHeadInBattleStateChanged,
            });
            headShowChangeActionMap.Add(EHeadShowChange.IsPlayerNameVisible,new HeadShowChangeAction
            {
                valueGetter = PlayerNameVisible,
                onValueChange = OnPlayerNameVisibleChanged,
            });
            headShowChangeActionMap.Add(EHeadShowChange.IsBaseInfoVisible,new HeadShowChangeAction
            {
                valueGetter = BaseInfoVisible,
                onValueChange = OnBaseInfoVisibleChanged,
            });
            headShowChangeActionMap.Add(EHeadShowChange.IsRageVisible,new HeadShowChangeAction
            {
                valueGetter = RageVisible,
                onValueChange = OnRageVisibleChanged,
            });
            headShowChangeActionMap.Add(EHeadShowChange.IsShowCommanderHeadPlayerName,new HeadShowChangeAction
            {
                valueGetter = CommanderHeadPlayerNameVisible,
                onValueChange = OnCommanderHeadPlayerNameVisibleChanged,
            });
            headShowChangeActionMap.Add(EHeadShowChange.IsBridgeHpVisible,new HeadShowChangeAction
            {
                valueGetter = BridgeHpVisible,
                onValueChange = OnBridgeHpVisibleChanged,
            });
            headShowChangeActionMap.Add(EHeadShowChange.IsNewYearHudVisible,new HeadShowChangeAction
            {
                valueGetter = NewYearHudVisible,
                onValueChange = OnNewYearHudVisibleChanged,
            });


            for (int i = 0; i < headShowChangePriority.Count; i++)
            {
                if (headShowChangeActionMap.TryGetValue(headShowChangePriority[i],out var action))
                {
                    headShowChangeActions.Add(action);
                }
            }

            foreach (var item in headFactorToShowRelation)
            {
                var list = item.Value;
                for (int i = 0; i < list.Count; i++)
                {
                    var k = list[i];
                    if (!headFactorToShowMap.TryGetValue(k, out var showData))
                    {
                        var action = GetFactorChangeAction(k);
                        var actionImmediately = GetFactorChangeActionImmediately(k);
                        showData = new HeadFactorData
                        {
                            showChangeType = new List<EHeadShowChange>(),
                            onValueChange = action,
                            onValueChangeImmediately = actionImmediately,
                        };
                        headFactorToShowMap.Add(k,showData);
                    }
                    showData.showChangeType.Add(item.Key);
                }
            }
        }

        private void InitHeadFactor()
        {
            SetHeadFactor(EHeadFactor.IsMonster,HudType == HudType.Monster);
            SetHeadFactor(EHeadFactor.IsInAllianceBuild,MarchEntity.RtsServerInfo.IsInAliinaceBuild());
            SetHeadFactor(EHeadFactor.IsInWonder,MarchEntity.RtsServerInfo.IsInWonder());
            SetHeadFactor(EHeadFactor.IsAssemblyMember,MarchEntity.RtsServerInfo.assemblyId != 0 && !MarchEntity.RtsServerInfo.isAssemblyLeader);
            SetHeadFactor(EHeadFactor.IsAssemblyLeader,MarchEntity.RtsServerInfo.isAssemblyLeader && MarchEntity.RtsServerInfo.Type == TargetCoordinateType.MARCH_3);

            bool isNotShowCommanderHead = HudType == HudType.Monster && (MarchEntity.RtsServerInfo.IsSumggler() || MarchEntity.RtsServerInfo.IsPracticeBoss() || MarchEntity.RtsServerInfo.IsWorldBoss());
            SetHeadFactor(EHeadFactor.IsNotShowCommanderHead, isNotShowCommanderHead);
            SetHeadFactor(EHeadFactor.IsDefenceTroop,MarchEntity.RtsServerInfo.DefenceTroop);
        }

        /// <summary>
        /// 刷新初始数据
        /// </summary>
        private void InitHeadShowData()
        {
            //初始化数据和表现
            foreach (var action in headShowChangeActions)
            {
                var value = action.valueGetter();
                action.value = value;
                action.onValueChange(value);
            }

            foreach (var data in headFactorToShowMap.Values)
            {
                data.onValueChange?.Invoke(data.value);
                data.onValueChangeImmediately?.Invoke(data.value);
            }
        }
        
        protected void SetHeadFactor(EHeadFactor factor,bool value)
        {
            if (headFactorToShowMap.TryGetValue(factor, out var show))
            {
                if (show.value != value)
                {
                    if (isDebug)
                    {
                        Log(factor+":" + value);
                    }
                    show.value = value;
                    //设置藏标记
                    var list = show.showChangeType;
                    for (int i = 0; i < list.Count; i++)
                    {
                        if (headShowChangeActionMap.TryGetValue(list[i],out var action))
                        {
                            action.isDirty = true;
                        }
                    }

                    if (show.onValueChange != null)
                    {
                        headFactorChangedList.Add(show);
                    }
                    show.onValueChangeImmediately?.Invoke(value);
                }
            }
        }

        protected void SetHeadShowDirty(EHeadShowChange type)
        {
            if (headShowChangeActionMap.TryGetValue(type, out var action))
            {
                action.isDirty = true;
            }
        }

        protected void UpdateHeadShow(EHeadShowChange type,bool force = false)
        {
            if (headShowChangeActionMap.TryGetValue(type, out var action))
            {
                var newValue = action.valueGetter();
                if (newValue != action.value || force)
                {
                    action.value = newValue;
                    action.onValueChange(newValue);
                    action.isDirty = false;
                }
            }
        }

        protected bool GetFactorValue(EHeadFactor factor)
        {
            if (headFactorToShowMap.TryGetValue(factor, out var action))
            {
                return action.value;
            }
            return false;
        }

        protected bool GetHeadShowValue(EHeadShowChange type)
        {
            if (headShowChangeActionMap.TryGetValue(type, out var action))
            {
                return action.value;
            }

            return false;
        }

        private bool IsRelatedInBattle()
        { 
            // 头像显示规则从之前的只显示自己和交战方 变为 显示所有 并且根据 精简模式 > 性能设置 > 设置面板勾选 的优先级判断开关
            var isRelated = GetFactorValue(EHeadFactor.IsAttackSelf) || GetFactorValue(EHeadFactor.IsAttackedBySelf) || GetFactorValue(EHeadFactor.IsTeamSelf);
            bool bShowHead = !RTSQualityHelper.IsSimpleMode && RTSQualityHelper.Quality > (int)QualityEnum.High && RTSQualityHelper.IsShowCommanderHead;
            bool isInBattle = GetFactorValue(EHeadFactor.IsInBattle) && !GetFactorValue(EHeadFactor.IsInAllianceBuild);
            if (bShowHead)
            {
                return isInBattle;
            }
            else
            {
                return isRelated && isInBattle;
            }
  
        }

        private void Log(object content)
        {
            Debug.LogError(MarchEntity.Tid +":HudBase " + content);
        }

        protected virtual void OnBridgeHpVisibleChanged(bool value)
        {
            
        }

        protected bool BridgeHpVisible()
        {
            var isInBattle = GetFactorValue(EHeadFactor.IsInBattle);
            var isBridge = GetFactorValue(EHeadFactor.IsBridge);
            return isInBattle && isBridge;
        }

        protected virtual void OnCommanderHeadPlayerNameVisibleChanged(bool value)
        {
            if (commanderHead)
            {
                commanderHead.SetPlayerNameEnable(value);
            }
        }
        
        private bool CommanderHeadPlayerNameVisible()
        {
            var isMonster = GetFactorValue(EHeadFactor.IsMonster);
            if (isMonster)
            {
                return false;
            }
            var isPoliceOffice = GetFactorValue(EHeadFactor.IsDefenceTroop);
            if (isPoliceOffice)
            {
                return false;
            }
            var isDefence = GetFactorValue(EHeadFactor.IsDefence);
            if (isDefence)
            {
                return false;
            }
            var isShowHead = GetHeadShowValue(EHeadShowChange.IsHeadVisible);
            if (!isShowHead)
            {
                return false;
            }

            var isInBattle = GetFactorValue(EHeadFactor.IsInBattle);
            var isSelected = GetFactorValue(EHeadFactor.IsSelected);
            if (isInBattle && !isSelected)
            {
                return true;
            }
            return false;
        }
        
        protected virtual void OnRageVisibleChanged(bool visible)
        {
            if (commanderHead)
            {
                // 血条和怒气槽
                var hpAndRage = commanderHead.HpAndRage;
                // 5. 战斗状态，显示怒气槽
                if (!visible)
                    hpAndRage.SetRageBarProgress(0);
                hpAndRage.SetRageBarActive(visible);

                SetRageHeroChanged(visible);
                //UpdateNamePosition();
            }
        }

        private bool RageVisible()
        {
            if (!GetHeadShowValue(EHeadShowChange.IsHeadVisible))
            {
                return false;
            }

            if (GetFactorValue(EHeadFactor.IsTruckFighting) || GetFactorValue(EHeadFactor.IsTrainFighting))
            {
                return false;
            }
            
            var isRelatedInBattle = IsRelatedInBattle();
            return isRelatedInBattle;
        }
        
        protected virtual void OnBaseInfoVisibleChanged(bool value)
        {
            if (value)
            {
                if (baseArmyInfo == null)
                {
                    SetBaseArmyInfo();
                }
            }
            if (baseArmyInfo)
            {
                baseArmyInfo.SetVisible(value);
                baseArmyInfo.SetSoldierTypeIcon(MarchEntity.RtsServerInfo);
                if (MarchEntity.ClientMarchType == EClientMarchType.Scout || MarchEntity.ClientMarchType == EClientMarchType.Rescue)
                {
                    baseArmyInfo.SetSoldierCountVisible(false);
                    baseArmyInfo.SetSoldierIconVisible(false);
                }
                else
                {
                    baseArmyInfo.SetSoldierCountVisible(true);
                    baseArmyInfo.SetSoldierIconVisible(true);
                }
            }
        }
        
        protected virtual void OnNewYearHudVisibleChanged(bool visible)
        {
            if (NewYearHudLod0 == null)
            {
                NewYearHudLod0 = ArmyManager.Instance.HudManager.GetHud(HudManager.NewYearHudLod0);                
            }
            NewYearHudLod0.SetActive(visible);
        }

        private bool NewYearHudVisible()
        {
            if (GetFactorValue(EHeadFactor.IsInBattle) || GetFactorValue(EHeadFactor.IsSelected))
            {
                return false;
            }
            
            return GetFactorValue(EHeadFactor.IsCanShowNewYearHud);
        }
        
        public void SetIsCanShowNewYearHud(bool value)
        {
            SetHeadFactor(EHeadFactor.IsCanShowNewYearHud, value);
        }

        private bool BaseInfoVisible()
        {
            if (GetFactorValue(EHeadFactor.IsMonster))
            {
                return false;
            }
            var isPolice = GetFactorValue(EHeadFactor.IsDefenceTroop);
            if (isPolice)
            {
                return false;
            }
            var isDefence = GetFactorValue(EHeadFactor.IsDefence);
            if (isDefence)
            {
                return false;
            }
            var IsArena = GetFactorValue(EHeadFactor.IsArena);
            if (IsArena)
            {
                return !GetFactorValue(EHeadFactor.IsEscaping);
            }

            var isExpedition = GetFactorValue(EHeadFactor.IsExpeditionDeck);
            if (isExpedition)
            {
                return true;
            }

            var isSelected = GetFactorValue(EHeadFactor.IsSelected);
            if (isSelected)
            {
                return true;
            }
            //以前的需求是选中都显示，策划要求改成选中部队时，不需要敌我双方都显示部队相信信息，只需要显示选中方。当前不管选中哪一方，都会显示双方的详情信息。
            //var isForceShow = GetFactorValue(EHeadFactor.IsForceShow);
            //if (isForceShow)// && !isBattleStyle)
            //{
            //    return true;
            //}
            return false;
        }

        public void SetNickName(string nickName)
        {
            if (MarchHudLod0)
            {
                MarchHudLod0.SetNickNameContent(nickName);
                if (MarchHudLod0.PlayerNameBg.gameObject.activeInHierarchy)
                {
                    MarchHudLod0.SetNickNameVisiable(true);
                }
                Color nameColor = GetNickNameColor(MarchEntity.Team);
                MarchHudLod0.PlayerNameText.color = nameColor;
                MarchHudLod0.SetNickNameColor(nameColor);
                //设置联盟icon
                MarchHudLod0.SetAllianceIconVisible(MarchEntity.RtsServerInfo.Type == TargetCoordinateType.ASSEMBLY_20);
                MarchHudLod0.SetPlayerTitleIconVisible(MarchEntity.RtsServerInfo.Type == TargetCoordinateType.MARCH_3 && GetHeadShowValue(EHeadShowChange.IsPlayerNameVisible));
            }
        }

        public void SetRenownName(string name,int quality)
        {
            if (MarchHudLod0)
            {
                MarchHudLod0.SetRenownNameContent(name);
                if (MarchHudLod0.PlayerNameBg.gameObject.activeInHierarchy)
                {
                    MarchHudLod0.SetRenownNameVisiable(true);
                }
                MarchHudLod0.RenownNameText.color = MarchHelper.RenownTxtColors[quality];
                MarchHudLod0.SetRenownNameColor(MarchHelper.RenownTxtColors[quality]);
            }
        }
        
        protected virtual void OnPlayerNameVisibleChanged(bool value)
        {
            if (MarchHudLod0!=null)
            {
                MarchHudLod0.PlayerNameBg.gameObject.SetActive(value);
                MarchHudLod0.SetNickNameVisiable(value);
                
                MarchHudLod0.RenownNameText.gameObject.SetActive(value);
                MarchHudLod0.SetRenownNameVisiable(value);
            }
        }

        private bool PlayerNameVisible()
        {
            if (GetHeadShowValue(EHeadShowChange.IsHeadVisible))
            {
                return false;
            }
            
            // var isCollecting = GetFactorValue(EHeadFactor.IsCollecting);
            var isInBuilding = GetFactorValue(EHeadFactor.IsInBuilding);
            var isDefence = GetFactorValue(EHeadFactor.IsDefence);
            var isAssembly = GetFactorValue(EHeadFactor.IsAssemblyLeader) ||
                             GetFactorValue(EHeadFactor.IsAssemblyMember);
            var isSelected = GetFactorValue(EHeadFactor.IsSelected);
            var IsPoliceOffice = GetFactorValue(EHeadFactor.IsDefenceTroop);
            var IsAssemblyWaiting = GetFactorValue(EHeadFactor.IsAssemblyWaiting);
            if (isInBuilding || isDefence || isAssembly || isSelected || IsPoliceOffice || IsAssemblyWaiting)
            {
                return false;
            }

            if (GetFactorValue(EHeadFactor.IsExpeditionDeck))
            {
                return false;
            }
            var isArena = GetFactorValue(EHeadFactor.IsArena) || (MarchEntity != null && MarchEntity.isArenaMarch);
            var isInBattle = GetFactorValue(EHeadFactor.IsInBattle);
            if (isArena)
            {
                return !isInBattle;
            }
            
            var isSelf = GetFactorValue(EHeadFactor.IsTeamSelf);

            if (isSelf)
            {
                if (GetFactorValue(EHeadFactor.IsAid))
                {
                    return false;
                }
                return !isInBattle;
            }

            var isAlly = GetFactorValue(EHeadFactor.IsTeamAlly);
            var isOther = GetFactorValue(EHeadFactor.IsTeamOther);
            var isAid = GetFactorValue(EHeadFactor.IsAid);
            if (isAid)
            {
                return (isAlly || isOther) && isInBattle;
            }
           
            return true;
        }
        
        protected virtual void OnCommanderHeadInBattleStateChanged(bool value)
        {
            
        }
        
        private bool CommanderHeadInBattleState()
        {
            if (!CommanderHeadVisible())
            {
                return false;
            }

            if (GetFactorValue(EHeadFactor.IsDefenceTroop) || GetFactorValue(EHeadFactor.IsCollecting) ||
                GetFactorValue(EHeadFactor.IsEscaping) || GetFactorValue(EHeadFactor.IsInBuilding) ||
                GetFactorValue(EHeadFactor.IsDefence) || GetFactorValue(EHeadFactor.IsBridge))
            {
                return false;
            }

            return GetFactorValue(EHeadFactor.IsInBattle);
        }

        private void OnCommanderHeadVisibleChanged(bool visible)
        {
            //Log("Visible = "+ visible);
            HeadVisibleChanged(visible);
        }

        protected virtual void HeadVisibleChanged(bool visible)
        {
            bool isCommanderHeadCreated = false;
            bool isCommanderHeadHiding = false;
            if (visible)
            {
                if (commanderHead == null)
                {
                    SetCommanderHead();
                    isCommanderHeadCreated = true;
                }
                else
                {
                    isHiding = false;
                }
                //MarchHudLod0.CommanderHead.BaseArmyInfo.SetSelect(_isSelected, MarchEntity.MarchInfo.IsInBattleState, _forceShowHud, _isBattleStyle);
                SetCommandHeadTeamInfo(_team);
                if (commanderHead!=null && commanderHead.MainCommander!=null)
                {
                    commanderHead.MainCommander.SetGatherFrame(MarchEntity.RtsServerInfo.isAssemblyLeader || MarchEntity.RtsServerInfo.isShowAssemblyHeadFrame);
                }
            }
            if (!visible && commanderHead != null)
            {
                isCommanderHeadHiding = true;
                RemoveCommanderHead(false);
            }


            if (commanderHead)
            {
                var hasShowHead = commanderHead.gameObject.activeSelf;
                if (!hasShowHead && !visible)
                {
                   
                }
                else if (visible)
                {
                    commanderHead.gameObject.SetActive(true);
                    if (!MarchEntity.MarchInfo.IsInBattleState)
                    {
                        commanderHead.PlayShowAni();
                    }
                    else
                    {
                        if (!isCommanderHeadHiding)
                        {
                            commanderHead.ClearHideAction();
                        }

                        if (MarchEntity.MarchInfo.MarchType != MarchType.DIE_5)
                        {
                            commanderHead.ClearDeadAction();
                        }
                        commanderHead.PlayDefaultState();
                    }
                }
            }
            UpdateHeadShow(EHeadShowChange.IsRageVisible,isCommanderHeadCreated);
            UpdateHeadShow(EHeadShowChange.IsShowCommanderHeadPlayerName,isCommanderHeadCreated);
            UpdateHeadShow(EHeadShowChange.IsPlayerNameVisible,isCommanderHeadCreated);
            UpdateHeadShow(EHeadShowChange.IsBaseInfoVisible,isCommanderHeadCreated);
            UpdateHeadShow(EHeadShowChange.IsBattleState,isCommanderHeadCreated);
            
            if (isCommanderHeadCreated)
            {
                UpdateHpToRealValue(true);
            }
        }
        
        protected virtual bool CommanderHeadVisible()
        {
            var isInBridge = GetFactorValue(EHeadFactor.IsBridge);
            if (isInBridge)
            {
                return false;
            }

            var isTruckFighting = GetFactorValue(EHeadFactor.IsTruckFighting);
            if (isTruckFighting)
            {
                return true;
            }
            
            var IsTrainFighting = GetFactorValue(EHeadFactor.IsTrainFighting);
            if (IsTrainFighting)
            {
                return true;
            }
            
            if (GetFactorValue(EHeadFactor.IsPracticeBoss))
            {
                return false;
            }
            var isReturningToNormalStyle = GetFactorValue(EHeadFactor.IsReturningToNormalStyle);
            if (isReturningToNormalStyle)
            {
                return true;
            }

            if (IsSiegeMarch())
            {
                return false;
            }
            var isAid = GetFactorValue(EHeadFactor.IsAid);
            var isInWonder = GetFactorValue(EHeadFactor.IsInWonder);
            if (isAid && isInWonder)
            {
                return false;
            }
            var isDefence = GetFactorValue(EHeadFactor.IsDefenceTroop) || GetFactorValue(EHeadFactor.IsDefence);
            var isSoldierEmpty = GetFactorValue(EHeadFactor.IsSoldierEmpty);
            if (isDefence && isSoldierEmpty)
            {
                return false;
            }
            var IsNotShowCommanderHead = GetFactorValue(EHeadFactor.IsNotShowCommanderHead);

            if (IsNotShowCommanderHead)
            {
                return false;
            }
            var isArena = GetFactorValue(EHeadFactor.IsArena);
            if (isArena)
            {
                return true;
            }

            var isExpedition = GetFactorValue(EHeadFactor.IsExpeditionDeck);
            if (isExpedition)
            {
                return true;
            }

            /*var isInBuilding = GetFactorValue(EHeadFactor.IsInBuilding);
            if (isInBuilding)
            {
                return false;
            }*/
            var isSelected = GetFactorValue(EHeadFactor.IsSelected);
            var isForceShow = GetFactorValue(EHeadFactor.IsForceShow);
            var isRelatedInBattle = IsRelatedInBattle();
            if (isForceShow)
            {
                if (GetFactorValue(EHeadFactor.IsInBattle) && !GetFactorValue(EHeadFactor.IsInAllianceBuild))
                {
                    return true;
                }
            }
            if (isSelected)
            {
                if (isRelatedInBattle)
                {
                    return true;
                }
                var isMonster = GetFactorValue(EHeadFactor.IsMonster);
                return !isMonster;
            }
            else
            {
                var isInAssembly = GetFactorValue(EHeadFactor.IsAssemblyLeader) ||
                                   GetFactorValue(EHeadFactor.IsAssemblyMember);
                if (isInAssembly)
                {
                    // 这里存在特殊情况 奇观中的部队是集结战斗 但是服务器不会创建集结部队对象 所以要让车头显示战斗头像
                    if (GetFactorValue(EHeadFactor.IsAssemblyLeader) && isInWonder && GetFactorValue(EHeadFactor.IsInBattle))
                    {
                        return true;
                    }
                    return false;
                }
                return isRelatedInBattle;
            }
        }

        private void ResetHeadShowChangeData()
        {
            foreach (var action in headShowChangeActions)
            {
                action.isDirty = false;
                action.value = false;
            }

            foreach (var data in headFactorToShowMap.Values)
            {
                data.value = false;
            }
            headFactorChangedList.Clear();
        }

        private void UpdateHeadShowChange()
        {
            foreach (var action in headShowChangeActions)
            {
                if (action.isDirty)
                {
                    action.isDirty = false;
                    var value = action.valueGetter();
                    if (value != action.value)
                    {
                        action.value = value;
                        action.onValueChange(value);
                    }
                }
            }

            if (headFactorChangedList.Count > 0)
            {
                for (int i = 0; i < headFactorChangedList.Count; i++)
                {
                    headFactorChangedList[i].onValueChange.Invoke(headFactorChangedList[i].value);
                }
                headFactorChangedList.Clear();
            }
        }
        
        public void SetIsSelfAttacked(bool value)
        {
            SetHeadFactor(EHeadFactor.IsAttackedBySelf,value);
        }
        public void SetAttackSelf(bool value)
        {
            SetHeadFactor(EHeadFactor.IsAttackSelf,value);
        }
        protected bool InInAllianceBuilding()
        {
            return MarchEntity.MarchInfo.ClientMarchStatue == EMarchStatus.InBuilding; //建造部队，服务器只给驻扎，不会给建造状态
        }
        public bool IsSelected
        {
            get
            {
                return _isSelected;
            }
        }
        protected bool _isSelected;
        protected float selectedScale = 1;

        public abstract void SetSelected(bool selected,bool isMultySelect);
        protected YImage[] images;
        protected List<YImage> commanderHeadImg = new List<YImage>(16);
        protected TMP_Text[] tmps;
        protected List<TMP_Text> commanderTmps = new List<TMP_Text>(2);
        public bool isPlayingDeadHudAni = false;
        public bool isPlayedDeadHudAni = false;
        protected float cachHeadScaleFlg = 0;
        protected bool _marchHudLod0BattleLineEnabled;
        public bool ForceShowHud
        {
            get
            {
                return _forceShowHud;
            }
        }
        protected bool _forceShowHud;

        public bool _isBattleStyleHud
        {
            get => m_isBattleStyleHud;
            set
            {
                if (ArmyManager.IsDebug && value != m_isBattleStyleHud)
                {
                    Debug.LogError(MarchEntity.Tid + " IsBattleStyleHud " + value);
                }
                m_isBattleStyleHud = value;
            }
        }
        private bool m_isBattleStyleHud = false;
        public bool ReturningNormalStyle = false;
        private float _hudReturnNormalStyleNeedTime;
        public float _hudReturnNormalStyleStartTime = 0;
        private Vector3 _hudReturnNormalStyleStartPos;
        private Vector3 _hudReturnNormalStyleStopPos;
        private bool needRecalculateBattleLineLength = true;
        private Vector3 lastHudOffset;
        protected void InitAlpha()
        {
            if (Lod0 != null)
            {
                images = Lod0.GetComponentsInChildren<YImage>();
                tmps = Lod0.GetComponentsInChildren<TMP_Text>();
            }
        }
        public virtual void Initialize(int team)
        {
            _localPosition = Vector3.zero;
            needRecalculateBattleLineLength = true;
            lastHudOffset = Vector3.zero;
            InitHeadShowChangeAction();
        }

        public void OnInit(MarchContext marchContext)
        {
            InitDefaultTrigger();
            InitParentScaleAndPosition();
            this.UpdateFollowPos();
            parentPos = MarchEntity.Transform.position;
            InitSoldierNumAndRage();
            SelfInit();
            SetSelected(false,false);
            OnCameraPosUpdated(marchContext);
            OnLodScaleChanged(marchContext);
            LodLevelChange(marchContext.LodLevel, marchContext.LodPercent, marchContext);
       
            InitHeadFactor();
            InitHeadShowData();
        }

        public abstract void UpdatePlayerName();

        private string heroIcon;

        protected virtual void InitCommanderHead()
        {
            // 主将、副将头像
            var heroIconList = _heroIconList;

            if (heroIconList == null)
            {
                if (MarchEntity != null)
                {
                    Debug.LogWarning(MarchEntity.Tid);
                }
                return;
            }
            // LOD0, 需要设置主将副将头像
            for (int i = 0; i < heroIconList.Length; i++)
            {
                if (i < HeroIcons.Length)
                {
                    HeroIcons[i] = heroIconList[i];
                }
            }

            commanderHead.SetPlayerNameTxt(MarchHudLod0.PlayerNameText.text);
            commanderHead.SetPlayerNameColor(MarchHelper.TeamTxtColors[_team]);
           
            // 部队有可能出现没有英雄信息的情况,如侦察
            if (heroIconList.Length >= 1)
            {
                string mainHeroIcon = heroIconList[GetCurHeroIdx()];
                heroIcon = mainHeroIcon;
                var mainCommander = commanderHead.MainCommander;
                mainCommander.SetHero(mainHeroIcon, true);
                SetCurHeroRageLimit();
                commanderHead.HpAndRage.Init();
                mainCommander.SetActive(true, true);
                mainCommander.QualityBG.enabled = false;
            }

            commanderHead.headIconSkill.gameObject.SetActive(false);
            if (MarchEntity.MarchInfo.SoldierCount != 0)
            {
                commanderHead.HpAndRage.SetHpActive(true);
            }
            else
            {
                commanderHead.HpAndRage.SetHpActive(false);
            }
            commanderHead.OnCommanderSwitchEvent = () =>
            {
                SwitchRageHero();
            };
        }

        public void SetHeroIcon(string[] iconList)
        {
            if (iconList == null)
            {
                return;
            }
            _heroIconList = iconList;
            //切换英雄时,设置怒气槽上限
            if (GetFactorValue(EHeadFactor.IsInBattle))
            {
                if (commanderHead && commanderHead.MainCommander)
                {
                    commanderHead.HpAndRage.SetRageBarMaxLimit(MaxRage,MarchEntity.CurHeroRageMax);
                }
            }

            var heroIconList = _heroIconList;
            var index = GetCurHeroIdx();
            if (heroIconList.Length > index)
            {
                string mainHeroIcon = heroIconList[index];
                if (heroIcon != mainHeroIcon)
                {
                    heroIcon = mainHeroIcon;
                    if (commanderHead && commanderHead.MainCommander)
                    {
                        var mainCommander = commanderHead.MainCommander;
                        mainCommander.SetHero(mainHeroIcon, true);
                    }
                }
            }
            SetCurHeroRageLimit();
        }
        
        protected abstract void InitSoldierNumAndRage();

        //显示所需数据
        protected int _team;

        public int Team => _team;
        protected string[] _heroIconList;
        protected int[] _heroQualityList;
        protected int _rageMaxList;

        public virtual void SetTeam(int team)
        {
            _team = team;
            /*if (_team == 0 && commanderHead == null)
            {
                SetCommanderHead();
            }*/
//            if (_team == 0 && commanderHead == null)
//            {
//                SetCommanderHead();
//            }
            if (commanderHead != null)
            {
                SetCommandHeadTeamInfo(team);
                commanderHead.SetPlayerNameColor(MarchHelper.TeamTxtColors[_team]);
            }
            if (baseArmyInfo)
            {
                var teamColor = GetNickNameColor(team);
                baseArmyInfo.SetTextColor(teamColor);
                if (MarchEntity.isArenaMarchInDeck || MarchEntity.isExpeditionMarch || MarchEntity.isExpeditionMarchInDeck)
                {
                    baseArmyInfo.ChangeSoldierCountVisibleForce(true);
                }
                else
                {
                    baseArmyInfo.ChangeSoldierCountVisiableByTeam(team);
                }
                baseArmyInfo.SetCount(MarchEntity.MarchInfo.SoldierCount);
            }
            if (MarchHudLod0!=null)
            {
                Color nameColor = GetNickNameColor(team);
                MarchHudLod0.PlayerNameText.color = nameColor;
                MarchHudLod0.SetNickNameColor(nameColor);
            }
        }

        private Color GetNickNameColor(int team)
        {
            Color c = MarchHelper.TeamTxtColors[team];
            RtsServerInfo serverInfo = MarchEntity.RtsServerInfo;
            if (serverInfo != null && serverInfo.CampId > 0 && team != (int)MarchTeam.Self) {
                // 如果阵营色有效(自己的部队不参与判断)
                c = MarchHelper.TeamTxtColors[serverInfo.CampId];
            }
            return c;
        }

        public void SetTsanTip(bool isWebHead, string headPath, string framePath, string desc)
        {
            var tsanTipObj = ArmyManager.Instance.HudManager.GetHud(HudManager.TsanTip);
            tsanTip = tsanTipObj.GetComponent<TsanTip>();
            tsanTipObj.transform.SetParent(MarchHudLod0.transform, false);
            tsanTipObj.transform.localPosition = Vector3.zero;
            tsanTipObj.transform.localRotation =  Quaternion.Euler(0, 0, 0);
            tsanTipObj.transform.localScale = Vector3.one;
            tsanTip.SetTsanTip(isWebHead, headPath, framePath, desc);
        }

        public void RemoveTsanTip()
        {
            if (tsanTip)
            {
                ArmyManager.Instance.HudManager.RecoverHud(HudManager.TsanTip, tsanTip.gameObject);
                tsanTip = null;
            }
        }

        private void SetCommanderHead()
        {
            if (MarchHudLod0 == null)
            {
                return;
            }
            if (!isHiding)
            {
                var commanderHeadObj = ArmyManager.Instance.HudManager.GetHud(HudManager.CommanderHead);
                commanderHead = commanderHeadObj.GetComponent<CommanderHead>();
                commanderHead.OnCommanderSwitchEvent = () =>
                {
                    SwitchRageHero();
                };
                commanderHead.OnEnabled();
                
                commanderHeadObj.transform.SetParent(MarchHudLod0.transform, false);
                
                commanderHeadObj.transform.localRotation = Quaternion.Euler(0, 0, 0);
                commanderHead.SetScale(BattleUtils.UnSelectedHudScale);
                cachHeadScaleFlg = commanderHead.MainCommander.transform.localScale.x;
                InitCommanderHead();
                _marchHudLod0BattleLineEnabled =commanderHead.BattleLine.enabled;
                if (commanderHead != null)
                {
                    if (commanderHeadImg.Count == 0)
                    {
                        commanderHead.GetComponentsInChildren<YImage>(commanderHeadImg);
                    }
                    if (commanderTmps.Count == 0)
                    {
                        commanderHead.GetComponentsInChildren<TMP_Text>(commanderTmps);
                    }
                }
                commanderHead.SetGray(MarchEntity.RtsServerInfo.marchType == MarchType.DIE_5);
                commanderHead.SetColliderInfo(MarchEntity.Mono.name);
                //MarchHudLod0.SetColliderEnable(true);

                SetCommanderHeadLocalPosition(commanderHeadObj);
                commanderHead.SetHeadScaleBySoldierCount();
            }
        }

        private void SetBaseArmyInfo()
        {
            if (commanderHead)
            {
                var baseArmyInfoObj = ArmyManager.Instance.HudManager.GetHud(HudManager.BaseArmyInfo);
                baseArmyInfo = baseArmyInfoObj.GetComponent<BaseArmyInfo>();
                var isSandBox = !(MarchEntity.isArenaMarchInDeck || MarchEntity.isExpeditionMarch ||
                                  MarchEntity.isExpeditionMarchInDeck);
                if (MarchEntity.isArenaMarchInDeck || MarchEntity.isExpeditionMarch || MarchEntity.isExpeditionMarchInDeck)
                {
                    baseArmyInfo.ChangeSoldierCountVisibleForce(true);
                }
                else
                {
                    baseArmyInfo.ChangeSoldierCountVisiableByTeam(_team);
                }
                var transform = baseArmyInfo.transform;
                transform.SetParent(commanderHead.baseArmyInfoParent);
                transform.localPosition = Vector3.zero;
                transform.localEulerAngles = Vector3.zero;
                transform.localScale = Vector3.one;
                
                bool isScoutMarch = (MarchEntity.MarchInfo.MarchEntity.ClientMarchType == EClientMarchType.Scout);
                bool isRescueMarch = MarchEntity.MarchInfo.MarchEntity.ClientMarchType == EClientMarchType.Rescue;
                if (isScoutMarch || isRescueMarch)
                {
                    baseArmyInfo.SetName(MarchHudLod0.PlayerNameText.text + "\n" + MarchEntity.RtsServerInfo.name);
                    baseArmyInfo.ChangeSoldierInfoActive(false);
                }
                else
                {
                    baseArmyInfo.SetName(MarchHudLod0.PlayerNameText.text);
                    baseArmyInfo.ChangeSoldierInfoActive(true);
                }

                baseArmyInfo.SetColliderActive(MarchEntity.MarchInfo.MarchEntity.ClientMarchType == EClientMarchType.March, MarchEntity.RtsServerInfo, isSandBox);
                baseArmyInfo.SetColliderInfo(MarchEntity.Mono.name);
                var teamColor = GetNickNameColor(_team);
                baseArmyInfo.SetTextColor(teamColor);
            }
        }
        
        private void SetCommandHeadTeamInfo(int team)
        {
            if (commanderHead)
            {
                commanderHead.MainCommander.SetTeam(team,MarchEntity.RtsServerInfo.isAssemblyLeader,false,ArmyManager.Instance.IsCustomHudMarchType(MarchEntity.ClientMarchType));
                //commanderHead.SubCommander.SetTeam(team);
                commanderHead.SetBattleLine(team);
            }
        }
        
        
        public abstract void OnCameraPosUpdated(MarchContext marchContext);
        public void OnUpdate(MarchContext marchContext)
        {
            if (_marchLodLevel <= WorldEntry.MaxShowMarchLodLevel)
            {
                OnUpdateLowLod(marchContext);
            }
            else
            {
                OnUpdateHighLod();
            }
            UpdateAlpha();
            UpdateShake();
            UpdateDirtyData();
            UpdateHeadShowChange();
        }

        protected virtual void OnUpdateHighLod()
        {

        }

        protected virtual void UpdateDirtyData()
        {
            if (MarchEntity!=null)
            {
                if (MarchEntity.MarchInfo.IsSoldierCountDirty && !GetFactorValue(EHeadFactor.IsInBattle))
                {
                    MarchEntity.MarchInfo.IsSoldierCountDirty = false;
                    UpdateHpToRealValue(true);
                }
            }
        }
        
        public void UpdateSoldierCount()
        {
            UpdateHpToRealValue(true);
        }

        private bool inBattleState;
        protected Action<bool> inBattleStateChangedAction;
        private bool m_isSelfInBattleState = false;
        /// <summary>
        /// 更新低Lod的东西，每帧调用，只更新需要每帧刷新的
        /// </summary>
        /// <param name="marchContext"></param>
        protected virtual void OnUpdateLowLod(MarchContext marchContext)
        {
            //更新ui位置
            UpdateLod0ScalePosition(marchContext);
        }
        private Vector3 change2BattleStylePositionStartPos;
        private void UpdateLod0ScalePosition(MarchContext context)
        {
            if (MarchHudLod0 == null || commanderHead == null)
            {
                return;
            }
            var isShowBattleStyleUI = GetHeadShowValue(EHeadShowChange.IsBattleState);//IsShowBattleStyleHud();//是否拉线
            if (!isShowBattleStyleUI) //未拉线
            {
                if (isHiding) //正在移除头像 直接返回
                {
                    _isBattleStyleHud = false;
                    return;
                }
                if (isPlayingDeadHudAni && !isPlayedDeadHudAni)//正在播放死亡头像动画 返回
                {
                    return;
                }
                if (_isBattleStyleHud)
                {
                    var time = TimeUtils.GetClientTickTime();
                    if (Math.Abs(_hudReturnNormalStyleStartTime) < 0.001f)
                    {
                        Vector3 targetPos;
                        if ((_isSelected || _forceShowHud) && !MarchEntity.isMonster)
                        {
                            targetPos = BattleUtils.SelectPosition;
                        }
                        else
                        {
                            targetPos = BattleUtils.SpreadPosition;
                        }
                        _hudReturnNormalStyleStartTime = time;
                        var worldTargetPos = MarchHudLod0.transform.TransformPoint(BattleUtils.SelectPosition);
                        var worldStartPos = commanderHead.transform.position;
                        _hudReturnNormalStyleNeedTime = Vector3.Distance(worldTargetPos, worldStartPos) / (hudMoveSpeed * 2f);
                        _hudReturnNormalStyleStartPos = commanderHead.transform.localPosition;
                        _hudReturnNormalStyleStopPos = targetPos;

                        if (_marchHudLod0BattleLineEnabled)
                        {
                            commanderHead.BattleLine.enabled = false;
                            _marchHudLod0BattleLineEnabled = false;
                        }
                    }
                    if (_hudReturnNormalStyleStartTime > 0)
                    {
                        if (time - _hudReturnNormalStyleStartTime < _hudReturnNormalStyleNeedTime)// && _hudReturnNormalStyleNeedTime > deletaTime )
                        {
                            var lerpTime = (time - _hudReturnNormalStyleStartTime) / _hudReturnNormalStyleNeedTime;
                            commanderHead.transform.localPosition = Vector3.Lerp(_hudReturnNormalStyleStartPos, _hudReturnNormalStyleStopPos, lerpTime);
                        }
                        else
                        {
                            commanderHead.transform.localPosition = _hudReturnNormalStyleStopPos;
                            _isBattleStyleHud = false;
                            if (_forceShowHud)
                            {
                                if (!MarchEntity.MarchInfo.IsInBattleState)
                                {
                                    _forceShowHud = false;
                                }
                            }
                            isPlayedDeadHudAni = false;
                            _hudReturnNormalStyleStartTime = 0;
                            _hudReturnNormalStyleNeedTime = 0;
                            SetHeadFactor(EHeadFactor.IsReturningToNormalStyle,false);
                            //UpdateLod0CommanderHead();
                        }
                    }
                }
                else
                {
                    Vector3 localPosition;
                    //防守状态时 角色头像需要在城的中间
                    if (IsBattleInCenterType())
                    {
                        localPosition = BattleFormationHelper.cityDefenceHudOffset;
                    }
                    else if (MarchType == MarchType.COLLECT_3 && inBattleState)
                    {
                        localPosition = BattleFormationHelper.cityDefenceHudOffset;
                    } 
                    else if (MarchEntity.RtsServerInfo.DefenceTroop)
                    {
                        localPosition = BattleFormationHelper.cityDefenceHudOffset;
                    }
                    else if (MarchType == MarchType.DIE_5)
                    {
                        if (_isSelected)
                        {
                            localPosition = BattleUtils.SelectPosition;
                        }
                        else
                        {
                            localPosition = BattleUtils.DeadPosition;
                        }
                        isPlayedDeadHudAni = false;
                        UpdateHeadShow(EHeadShowChange.IsHeadVisible);
                    }
                    else
                    {
                        if (!MarchEntity.isMonster)
                        {
                            localPosition = BattleUtils.SelectPosition;
                        }
                        else
                        {
                            localPosition = BattleUtils.SpreadPosition;
                        }
                    }

                    if (_localPosition != localPosition)
                    {
                        _localPosition = localPosition;
                        commanderHead.transform.localPosition = _localPosition;
                        hudBattleFinalPosition = Vector3.zero;
                        OnBattleStyleToNormalStyle();
                    }
                    if (_marchHudLod0BattleLineEnabled)
                    {
                        if (commanderHead)
                        {
                            commanderHead.BattleLine.enabled = false;
                            _marchHudLod0BattleLineEnabled = false;
                        }
                    }
                }
            }
            else
            { //正在拉线
                if (!_isBattleStyleHud)
                {
                    if (MarchEntity.isMonster)
                    {
                        commanderHead.transform.localPosition = BattleUtils.SpreadPosition;
                        commanderHead.CanvasGroup.alpha = 0;
                    }
                    else
                    {
                        if (_isSelected)
                        {
                            commanderHead.transform.localPosition = BattleUtils.SelectPosition;
                            commanderHead.CanvasGroup.alpha = 1;
                        }
                        else
                        {
                            commanderHead.transform.localPosition = BattleUtils.SpreadPosition;
                            commanderHead.CanvasGroup.alpha = 0;
                        } 
                    }
                }
                _isBattleStyleHud = true;
                //var isSelfJoinedBattle = false;
                if (commanderHead != null)
                {
                    UpdateBattleUI(context, ref _marchHudLod0BattleLineEnabled, GetFactorValue(EHeadFactor.IsInBattle));
                }
            }
        }

        protected virtual void SetCommanderHeadLocalPosition(GameObject commanderHeadObj)
        {
            if (commanderHeadObj == null)
            {
                return;
            }

            if (IsBattleInCenterType())
            {
                commanderHeadObj.transform.localPosition = BattleFormationHelper.cityDefenceHudOffset;
                return;
            }
            if (MarchEntity.MarchInfo.MarchType == MarchType.COLLECT_3 && MarchEntity.MarchInfo.IsInBattleState)
            {
                commanderHeadObj.transform.localPosition = BattleFormationHelper.cityDefenceHudOffset;
                return;
            }
            if (MarchEntity.RtsServerInfo.DefenceTroop)
            {
                commanderHeadObj.transform.localPosition = BattleFormationHelper.cityDefenceHudOffset;
                return;
            }
            if (MarchEntity.MarchInfo.MarchType == MarchType.DIE_5)
            {
                if (_isSelected)
                {
                    commanderHeadObj.transform.localPosition = BattleUtils.SelectPosition;
                }
                else
                {
                    commanderHeadObj.transform.localPosition = BattleUtils.DeadPosition;

                }
                return;
            }
            if (MarchEntity.MarchInfo.IsInBattleState)
            {
                commanderHeadObj.transform.localPosition = Vector3.zero;
            }
            else
            {
                if (_isSelected)
                {
                    commanderHeadObj.transform.localPosition = BattleUtils.SelectPosition;
                }
                else
                {
                    commanderHeadObj.transform.localPosition = Vector3.zero;
                }
            }
        }

        protected virtual void OnBattleStyleToNormalStyle()
        {
            
        }

        protected bool IsShowBattleStyleHud()
        {
            bool isShowBattleStyleUI;
            var isInBattle = GetFactorValue(EHeadFactor.IsInBattle);
            var isForceShow = GetFactorValue(EHeadFactor.IsForceShow);
            var isSelected = GetFactorValue(EHeadFactor.IsSelected);
            if (!isInBattle)
            {
                isShowBattleStyleUI = isForceShow || isSelected;
            }
            else
            {
                var isEscape = GetFactorValue(EHeadFactor.IsEscaping);
                var isInCollect = GetFactorValue(EHeadFactor.IsCollecting);
                var isDefence = GetFactorValue(EHeadFactor.IsDefence);
                var isInBuilding = GetFactorValue(EHeadFactor.IsInBuilding);
                isShowBattleStyleUI = !isInCollect && !isDefence && !isEscape && !isInBuilding;
            }
            return isShowBattleStyleUI;
        }
        protected bool commanderSelectedChange;
        
        

        public void SetSelectedScale(float scale)
        {
            selectedScale = scale;
        }
        /// <summary>
        /// 修改头像尺寸
        /// </summary>
        protected void UpdateCommanderHeadScale()
        {
            float scale = selectedScale;
            if (scale != cachHeadScaleFlg)
            {
                if (commanderHead)
                {
                    cachHeadScaleFlg = scale;
                    commanderHead.SetScale(cachHeadScaleFlg);
                }
            }
        }
        

        public virtual void UpdateHpToRealValue(bool forceFresh = false)
        {
            var soldierCount = MarchEntity.MarchInfo.SoldierCount;
            if (commanderHead)
            {
                float ratio = 0;
                if (!ArmyManager.Instance.IsCustomHudMarchType(MarchEntity.ClientMarchType))
                {
                    //这段代码是原来的代码,我先没动(原来是如果是scout就不显示血条.现在需要显示,且ratio为1)
                    var isShowSoldierCount = MarchEntity.ClientMarchType != EClientMarchType.Scout;
                    bool isSelf = (_team == (int)MarchTeam.Self);
                    commanderHead.HpAndRage.SetVisible(isSelf || (isShowSoldierCount && soldierCount < MarchEntity.MarchInfo.InitSoldierCount));
                    var totalCount = MarchEntity.MarchInfo.InitSoldierCount;
                    ratio = (float) soldierCount / totalCount;
                    if (ratio > 1)
                        ratio = 1;
                }
                else
                {
                    commanderHead.HpAndRage.SetVisible(true);
                    ratio = 1;
                }
       
                commanderHead.SetHeadScaleBySoldierCount();
                commanderHead.HpAndRage.SetHpBarProgress(ratio,forceFresh);
                commanderHead.MainCommander.SetHpBarProgress(ratio,forceFresh);
                if (baseArmyInfo)
                {
                    baseArmyInfo.SetCount(soldierCount);
                }
            }
        }
        
        private void UpdateAlpha()
        {
            if (isTweenAlpha)
            {
                if (currentTime < tweenAlphaTime)
                {
                    currentAlpha = Mathf.Lerp(startAlpha, targetAlpha, currentTime / tweenAlphaTime);
                    SetHudAlpha(currentAlpha);
                }
                else
                {
                    isTweenAlpha = false;
                    SetHudAlpha(targetAlpha);
                }
                currentTime += Time.deltaTime;
            }
        }

        private void SetHudAlpha(float alpha)
        {
            if (tmps!=null)
            {
                for (int i = 0; i < tmps.Length; i++)
                {
                    var color = tmps[i].color;
                    color.a = alpha;
                    tmps[i].color = color;
                }
            }

            if (commanderTmps != null)
            {
                for (int i = 0; i < commanderTmps.Count; i++)
                {
                    var color = commanderTmps[i].color;
                    color.a = alpha;
                    commanderTmps[i].color = color;
                }
            }
        }

        protected Vector3 invisiblePosition = new Vector3(-999,-999,-999);
        public virtual void Hide()
        {
            //SetHudAlpha(0);
            if (Lod0)
            {
                Lod0.transform.localPosition = invisiblePosition;
            }

            if (Lod1)
            {
                Lod1.transform.localPosition = invisiblePosition;
            }
            ResetData();
        }

        public virtual void Show()
        {
            //SetHudAlpha(1);
        }
        
        protected abstract void InitDefaultTrigger();

        public virtual void RoundFight(int soldierCurrentCount, int totalSoldierCount, bool isInBattle)
        {
            SetIsInBattle(isInBattle);
            SetHeadFactor(EHeadFactor.IsSoldierEmpty,MarchEntity.MarchInfo.SoldierCount == 0);
        }
        public virtual void Dispose()
        {
            ResetData();
        }

        public virtual void ResetData()
        {
            _marchLodLevel = -1;
            BattleTargetId = 0;
            target = null;
            isHiding = false;
            commanderSelectedChange = false;
            isPlayedDeadHudAni = false;
            IsAttackSelf = false;
            IsSelfAttacked = false;
            _isSelected = false;
            isPlayingDeadHudAni = false;
            inBattleState = false;
            _isBattleStyleHud = false;
            _forceShowHud = false;
            _hudReturnNormalStyleStartTime = 0;
            _hudReturnNormalStyleNeedTime = 0;
            battleLineLocalPosition = default;
            cachHeadScaleFlg = 0;
            _localPosition = default;
            hudBattleFinalPosition = default;
            needRecalculateBattleLineLength = true;
            lastHudOffset = Vector3.zero;
            tmps = null;
            images = null;
            commanderHeadImg.Clear();
            commanderTmps.Clear();
            m_isSelfInBattleState = false;
            ResetHeadShowChangeData();
            heroIcon = null;
            moveHudStartTime = 0;
            _marchHudLod0BattleLineEnabled = false;
        }

        //public virtual void SetLod0NickName(TroopMarch troopMarch)
        //{

        //}
        public void SetIsInBattle(bool isInBattle)
        {
            SetHeadFactor(EHeadFactor.IsInBattle,isInBattle);
        }

        public void SetIsTruckFighting(bool isFighting)
        {
            SetHeadFactor(EHeadFactor.IsTruckFighting,isFighting);
            SetHeadFactor(EHeadFactor.IsInBattle,isFighting);
        }

        public void SetIsTrainFighting(bool isFighting)
        {
            SetHeadFactor(EHeadFactor.IsTrainFighting,isFighting);
            SetHeadFactor(EHeadFactor.IsInBattle,isFighting);
        }

        public void SetNewYearHudVisible(bool value)
        {
            if (NewYearHudLod0 == null)
            {
                NewYearHudLod0 = ArmyManager.Instance.HudManager.GetHud(HudManager.NewYearHudLod0);
            }
            NewYearHudLod0.SetActive(value);
        }

        public void SetNewYearHudArgus(float cdTime, string iconPath, LuaFunction luaCallback)
        {
            var newYearHudLod0 = NewYearHudLod0.GetComponent<NewYearHudLod0>();
            newYearHudLod0.SetClickCDTime(cdTime);
            newYearHudLod0.SetIconImagePath(iconPath);
            newYearHudLod0.SetClickCallback(luaCallback);
        }
        
        public void SetNewYearHudIconPath(string iconPath)
        {
            var newYearHudLod0 = NewYearHudLod0.GetComponent<NewYearHudLod0>();
            newYearHudLod0.SetIconImagePath(iconPath);
        }
        
        public virtual void OnUpdateMarchTypeAndStatus()
        {
            MarchType = MarchEntity.MarchInfo.MarchType;
            ClientMarchStatus = MarchEntity.MarchInfo.ClientMarchStatue;
            SetHeadFactor(EHeadFactor.IsCollecting,ClientMarchStatus == EMarchStatus.Collect);
            SetHeadFactor(EHeadFactor.IsDefence,MarchType == MarchType.DEFENCE_6);
            SetHeadFactor(EHeadFactor.IsAid,MarchType == MarchType.AID_8 && MarchEntity.MarchInfo.BuildingUid != 0);
            SetHeadFactor(EHeadFactor.IsEscaping,ClientMarchStatus == EMarchStatus.Escape || MarchType == MarchType.DIE_5);
            SetHeadFactor(EHeadFactor.IsInBuilding,ClientMarchStatus == EMarchStatus.InBuilding || MarchEntity.isFakeChild);
            SetHeadFactor(EHeadFactor.IsSoldierEmpty,MarchEntity.MarchInfo.SoldierCount == 0);
            SetHeadFactor(EHeadFactor.IsBridge,MarchEntity.isFakeParent);
            SetHeadFactor(EHeadFactor.IsAssemblyMember,MarchEntity.RtsServerInfo.assemblyId != 0 && !MarchEntity.RtsServerInfo.isAssemblyLeader);
            SetHeadFactor(EHeadFactor.IsAssemblyLeader,MarchEntity.RtsServerInfo.isAssemblyLeader && MarchEntity.RtsServerInfo.Type == TargetCoordinateType.MARCH_3);
            SetHeadFactor(EHeadFactor.IsAssemblyWaiting,MarchEntity.RtsServerInfo.marchStatus == MarchStatus.GARRISON_3 && MarchEntity.RtsServerInfo.Type == TargetCoordinateType.ASSEMBLY_20);
            SetHeadFactor(EHeadFactor.IsArena,MarchEntity.isArenaMarchInDeck);
            SetHeadFactor(EHeadFactor.IsPracticeBoss, MarchEntity.RtsServerInfo.Type == TargetCoordinateType.ALLIANCE_PRACTICE_BOSS_32);

            
            SetHeadFactor(EHeadFactor.IsExpeditionDeck,MarchEntity.isExpeditionMarchInDeck);
            SetHeadFactor(EHeadFactor.IsInAllianceBuild,MarchEntity.RtsServerInfo.IsInAliinaceBuild());
            SetHeadFactor(EHeadFactor.IsInWonder,MarchEntity.RtsServerInfo.IsInWonder());
            SetHeadFactor(EHeadFactor.IsTruckFighting,false);
            SetHeadFactor(EHeadFactor.IsTrainFighting,false);
            SetBattleLineLength();
            //UpdateLod0CommanderHead();
        }

        

        public void ShowSkillFocusEffect()
        {
            if (Lod0 == null)
            {
                return;
            }
            if (Lod0.activeInHierarchy)
            {
                if (commanderHead)
                {
                    commanderHead.ShowSkillFocusEffect();
                }
            }
        }

        internal void UpdateRage(int rage, int lastRage, int costRage)
        {
            if (MarchHudLod0 == null)
            {
                return;
            }
            if (commanderHead)
            {
                commanderHead.HpAndRage.SetRoundRage(lastRage, costRage, rage, MaxRage,MarchEntity.CurHeroRageMax);
            }
        }

        public void ShowReleaseSkillEffect(int heroId, string skillName, int heroIndex,string monsterSkillIcon = null)
        {
            if (MarchHudLod0 == null)
            {
                return;
            }
            if (commanderHead && commanderHead.gameObject.activeInHierarchy)
            {
                int index = MarchEntity.MarchInfo.HeroList.IndexOf(heroId);
                string icon = string.Empty;
                if (index >= 0 && HeroIcons.Length > index)
                {
                    icon = HeroIcons[index];
                }
                commanderHead.ShowReleaseSkillEffect(heroId, skillName, heroIndex, icon,monsterSkillIcon);
            }
        }

        public void ShowSkillHitEffect()
        {
            if (Lod0!=null && Lod0.activeInHierarchy)
            {
                commanderHead?.ShowSkillHitEffect();
            }
        }
        public void SetBattleTargetId(long targetId,TargetCoordinateType attackTargetType)
        {
            if (targetId == 0 || targetId == MarchEntity.MarchInfo.Uid)
            {
                BattleTargetId = 0;
                return;
            }
            if (targetId!= BattleTargetId && BattleTargetId != 0)
            {
                MarchEntity.RemoveAttack();
            }
            BattleTargetId = targetId;
            if (MarchEntity.MarchInfo.Team != 0)
            {
                var targetEntity = ArmyManager.Instance.MarchManager.GetMarchEntityByIdAndType(targetId,(com.youzu.warh.protocol.TargetCoordinateType)attackTargetType);
                if (targetEntity != null)
                {
                    IsAttackSelf = targetEntity.MarchInfo.Team == 0 || targetEntity.RtsServerInfo.isAssemblyLeader && targetEntity.MarchInfo.Team == 1;
                    if (ArmyManager.IsDebug)
                    {
                        Debug.LogError(MarchEntity.Tid + " SetTargetId " + targetId + " " + targetEntity.MarchInfo.Team);
                    }
                }
                else
                {
                    IsAttackSelf = false;
                    if (ArmyManager.IsDebug)
                    {
                        Debug.LogError(MarchEntity.Tid + " SetTargetId " + targetId + " null");
                    }
                }
            }
        }

        protected virtual void LodLevelChange(int currentLodLevel, float currentLodPercent, MarchContext marchContext)
        {
            
        }

        public virtual void OnLodScaleChanged(MarchContext marchContext)
        {
            needRecalculateBattleLineLength = true;
            if (marchContext.LodLevel < 3)
            {
                OnLod0ScaleChanged(marchContext);
            }
            else
            {
                OnLod1ScaleChanged(marchContext);
            }
        }

        protected abstract void OnLod1ScaleChanged(MarchContext marchContext);
        protected abstract void OnLod0ScaleChanged(MarchContext marchContext);

        protected void SetHudLodScale(LodHudType hudType,GameObject obj, MarchContext marchContext)
        {
            if (obj is null)
            {
                return;
            }

            var lodLevel = marchContext.LodLevel;
            var lodPercent = marchContext.LodPercent;
            var height = marchContext.CameraHeight;
            var rules = HudLodScaleConfig.HudScaleConfig[hudType];
            if (rules.Length > 0)
            {
                //如果不满足最低lod缩放，则用最低的lod缩放
                if (lodLevel <= rules[0].StartLod && lodPercent <= rules[0].StartPercent)
                {
                    Vector3 _localScale = new Vector3(rules[0].StartScale, rules[0].StartScale, rules[0].StartScale);
                    obj.transform.localScale = _localScale;
                    if (hudType == LodHudType.LodLowArmyInfo)
                    {
                        MarchHudLod0?.SetNickNameScale(rules[0].StartScale);
                        MarchHudLod0?.SetRenownNameScale(rules[0].StartScale);
                    }
                    return;
                }
                //如果比最高lod缩放还大，则用最大的的缩放
                if (lodLevel >= rules[rules.Length - 1].EndLod && lodPercent > rules[rules.Length - 1].EndPercent)
                {
                    obj.transform.localScale = new Vector3(rules[rules.Length - 1].EndScale,
                        rules[rules.Length - 1].EndScale, rules[rules.Length - 1].EndScale);
                    if (hudType == LodHudType.LodLowArmyInfo)
                    {
                        MarchHudLod0?.SetNickNameScale(rules[rules.Length - 1].EndScale);
                        MarchHudLod0?.SetRenownNameScale(rules[rules.Length - 1].EndScale);
                    }
                    return;
                }
                for (int i = 0; i < rules.Length; i++)
                {
                    //遍历判断当前缩放在范围内的配置
                    bool inRules = (lodLevel > rules[i].StartLod || (lodLevel == rules[i].StartLod && lodPercent >= rules[i].StartPercent)) &&
                                   (lodLevel < rules[i].EndLod || (lodLevel == rules[i].EndLod && lodPercent <= rules[i].EndPercent));
                    if (!inRules)
                    {
                        continue;
                    }

                    var start = rules[i].StartLod * 100 + rules[i].StartPercent;
                    var end = rules[i].EndLod * 100 + rules[i].EndPercent;
                    var current = lodLevel * 100 + lodPercent;

                    var progress = (current - start) / (end - start);
                    var scale = Mathf.Lerp(rules[i].StartScale, rules[i].EndScale, progress);
                    obj.transform.localScale = new Vector3(scale, scale, scale);
                    if (hudType == LodHudType.LodLowArmyInfo)
                    {
                        MarchHudLod0?.SetNickNameScale(scale);
                        MarchHudLod0?.SetRenownNameScale(scale);
                    }
                }
            }
        }
        protected Vector3 hudBattleFinalPosition;
        protected Vector3 hudBattleStartPosition;
        protected Vector3 battleLineLocalPosition;
        protected float moveHudStartTime;
        protected Vector3 vec;
        protected Vector3 returnVec;
        protected float hudMoveSpeed = 1.5f;
        protected float needTime;
        private float lineLength = 125f;
        private float entityRadius;

        private void SetBattleLineLength()
        {
            if (MarchType == MarchType.AID_8 && MarchEntity.MarchInfo.MarchStatus == MarchStatus.FIGHT_2 && MarchEntity.MarchInfo.BuildingUid != 0)
            {
                lineLength = 170f;
                entityRadius = 1.35f / 2;
            }
            else
            {
                lineLength = 135f;
                entityRadius = 0.85f / 2;
            }
        }
        
        
        //需求：头像边缘要和部队半径边缘相切
        protected Vector3 CalMarchHudOffset(MarchContext context, Vector3 targetPosition)
        {
            if (commanderHead.BattleLine && battleLineLocalPosition == Vector3.zero)
            {
                battleLineLocalPosition = commanderHead.transform.position - commanderHead.BattleLine.transform.position;
            }
            var selfPosition = new Vector3(MarchEntity.MarchInfo.Position.x, MarchEntity.MarchInfo.Position.y, MarchEntity.MarchInfo.Position.z);
            if (IsSelected)
            {
                selfPosition.y += 0.5f;
            }
            //var targetPos = new Vector3(targetPosition.x, targetPosition.y, targetPosition.z);
            
            //if (needRecalculateBattleLineLength)
            //{
                var directionWorld = (selfPosition - targetPosition).normalized;
            
                //方阵的半径
                var radius = entityRadius;
                var edgePointWorld = selfPosition + directionWorld * radius;
                var edgePointScreen = WorldCameraManager.mainCamera.WorldToScreenPoint(edgePointWorld);
            
           
            
                var selfScreenPosition = WorldCameraManager.mainCamera.WorldToScreenPoint(selfPosition);
                //var targetScreenPosition = WorldCameraManager.mainCamera.WorldToScreenPoint(targetPosition);
                var directionScreen = (edgePointScreen - selfScreenPosition).normalized;
                //}

                var lineScreenPosition =
                    WorldCameraManager.mainCamera.WorldToScreenPoint(commanderHead.BattleLine.transform
                        .position);
            var linePosOffset =
                lineScreenPosition - WorldCameraManager.mainCamera.WorldToScreenPoint(commanderHead.transform.position);

            var lineToCenterDistance = Vector2.Distance(lineScreenPosition,
                WorldCameraManager.mainCamera.WorldToScreenPoint(commanderHead.MainCommander.edge.position));
            
            var screenDistance = Vector2.Distance(edgePointScreen, selfScreenPosition) + lineToCenterDistance;
            
            var offset = selfScreenPosition + directionScreen.normalized * screenDistance - linePosOffset;
            offset = WorldCameraManager.mainCamera.ScreenToWorldPoint(offset);


            if (lastHudOffset != offset)
            {
                needRecalculateBattleLineLength = true;
                lastHudOffset = offset;
            }
            //offset += battleLineLocalPosition;
            return offset;
        }



        protected void SetMarchHudOffset(Vector3 position, float moveTime)
        {
            if (position != hudBattleFinalPosition)
            {
                hudBattleFinalPosition = position;
                if (MarchEntity.MarchInfo.Position == Vector3.zero || Lod0.transform.position == Vector3.zero)
                {
                    hudBattleStartPosition = MarchEntity.MarchInfo.Position + BattleFormationHelper.hudOffset + BattleUtils.SelectPosition;
                }
                else
                {
                    hudBattleStartPosition = commanderHead.transform.position;
                }
                vec = (hudBattleFinalPosition - hudBattleStartPosition).normalized;
                needTime = Vector3.Distance(hudBattleFinalPosition, hudBattleStartPosition) / hudMoveSpeed;
                moveHudStartTime = Time.time;
            }
        }

        protected void UpdateBattleLinePos(YImage lineObj = null)
        {
            if (lineObj == null || commanderHead == null)
            {
                return;
            }


            Vector3 source = WorldCameraManager.mainCamera.WorldToScreenPoint(lineObj.transform.position);
            Vector3 target = WorldCameraManager.mainCamera.WorldToScreenPoint(MarchEntity.MarchInfo.Position);

            
            float a = target.x - source.x;
            float b = source.y - target.y;
            if (b == 0)
            {
                return;
            }
            float angle = Mathf.Atan(a / b) * Mathf.Rad2Deg - 90;
            if (b < 0)
            {
                angle = angle + 180;
            }
            lineObj.transform.localRotation = Quaternion.Euler(0, 0, angle);
            
            
            //检查是否需要重新计算线的长度
            if (!needRecalculateBattleLineLength)
            {
                return;
            }
            
            //线的长度
            RectTransformUtility.ScreenPointToLocalPointInRectangle(lineObj.rectTransform, source,
                WorldCameraManager.mainCamera, out var p1);
            RectTransformUtility.ScreenPointToLocalPointInRectangle(lineObj.rectTransform, target,
                WorldCameraManager.mainCamera, out var p2);
            var distance = Vector2.Distance(p1, p2);
            
            //简化公式
            var localScale = lineObj.transform.localScale;
            localScale.x = -1;
            lineObj.transform.localScale = localScale;
            var sizeDelta = lineObj.rectTransform.sizeDelta;
            lineObj.rectTransform.sizeDelta = new Vector2(distance, sizeDelta.y);
        }

        protected void UpdateBattleUI(MarchContext context,ref bool _marchHudLod0BattleLineEnabled,bool isSelfJoinedBattle)
        {
            var targetPosition = MarchEntity.MarchInfo.GetTargetPosition();
            var tempTarget = MarchEntity.GetBattleTarget();
            if (tempTarget != null)
            {
                if (target == null || tempTarget.Tid != target.Tid || tempTarget.TargetCoordinateType != target.TargetCoordinateType)
                {
                    target = tempTarget;
                }
            }
            if (target != null)// && targetPosition != tempTargetPosition)//计算HUD偏移
            {
                targetPosition = target.Position;
            }
            var offsetTargetPosition = CalMarchHudOffset(context, targetPosition);
            SetMarchHudOffset(offsetTargetPosition, 0.5f);
            if (!_marchHudLod0BattleLineEnabled)
            {
                commanderHead.BattleLine.enabled = true;
                _marchHudLod0BattleLineEnabled = true;
            }
            UpdatePosition(Time.deltaTime, isSelfJoinedBattle || GetFactorValue(EHeadFactor.IsReturningToNormalStyle));
            UpdateBattleLinePos(commanderHead.BattleLine);
        }
        public virtual void UpdateFollowPos()
        {
            
        }
        protected void UpdatePosition(float deltaTime, bool needLerp)
        {
            if (needLerp)
            {
                if (TimeUtils.GetClientTickTime() - moveHudStartTime < needTime && needTime > deltaTime)
                {
                    commanderHead.transform.position += vec * hudMoveSpeed * deltaTime;
                    commanderHead.CanvasGroup.alpha += (1f / needTime) * deltaTime;
                }
                else
                {
                    commanderHead.transform.position = hudBattleFinalPosition;
                    commanderHead.CanvasGroup.alpha = 1;
                }
            }
            else
            {
                commanderHead.transform.position = hudBattleFinalPosition;
                commanderHead.CanvasGroup.alpha = 1;
            }

            _localPosition = commanderHead.transform.localPosition;
            UpdateShake();
        }

        protected void RemoveCommanderHead(bool force = false)
        {
            if (commanderHead && !isHiding && !force)
            {
                isHiding = true;
                commanderHead.BattleLine.enabled = false;
                commanderHead.PlayHideAni(() =>
                {
                    RemoveCommander(true);
                });
            }
            if (force)
            {
                RemoveCommander();
            }
        }
        protected void RemoveCommander(bool isDelay = false)
        {
            //判断现在的状态是否真的需要移除，可能有动画播完延迟回调导致状态错误
            if (isDelay && !isHiding)
            {
                return;
            }
            if (MarchHudLod0 == null)
            {
                return;
            }
            if (commanderHead)
            {
                commanderHead.OnCommanderSwitchEvent = null;
                commanderHead.SetGray(false);
                commanderHead?.Dispose(true);
                ArmyManager.Instance.HudManager.RecoverHud(HudManager.CommanderHead, commanderHead.gameObject);
                MarchHudLod0.CommanderHead = null;
                commanderHead = null;
            }
            commanderHeadImg.Clear();
            commanderTmps.Clear();
            isHiding = false;
            _isBattleStyleHud = false;
            SetHeadFactor(EHeadFactor.IsReturningToNormalStyle,false);

            if (baseArmyInfo)
            {
                ArmyManager.Instance.HudManager.RecoverHud(HudManager.BaseArmyInfo, baseArmyInfo.gameObject);
                baseArmyInfo = null;
            }
        }
        public void TurnAlphaTo(float alpha)
        {
            isTweenAlpha = true;
            targetAlpha = alpha;
            startAlpha = Alpha;
            currentTime = 0;
            Alpha = alpha;
        }

        public abstract void ForceShowSelectedUI(bool isShow,bool isBattleStyle);


        public void ResetHudToNormalStyle()
        {
            if (!GetHeadShowValue(EHeadShowChange.IsHeadVisible))
            {
                return;
            }

            if (GetFactorValue(EHeadFactor.IsEscaping))
            {
                return;
            }
            if (_isBattleStyleHud)
            {
                SetHeadFactor(EHeadFactor.IsReturningToNormalStyle,true);
                if (ArmyManager.IsDebug)
                {
                    Debug.LogError(MarchEntity.Tid + " 结束拉线");
                }
            }
            MarchEntity.MarchInfo.FightFrameTime = 0;
            MarchEntity.RemoveAttack(); 
            TurnAlphaTo(1);
            if (_isSelected)
            {
                ArmyManager.Instance.MarchManager.SelectBattleTroop(MarchEntity.MarchInfo.Uid,MarchEntity.TargetCoordinateType, 1f, _team);
            }
            target = null;
        }

        //战斗时不拉线，头像在中间的类型
        private bool IsBattleInCenterType()
        {
            var isDefence = GetFactorValue(EHeadFactor.IsDefence);
            var isBridge = GetFactorValue(EHeadFactor.IsBridge);
            return isDefence || isBridge;
        }
        
        private float shakeStartTime;
        private float shakeDuration;
        private float shakeCdTime;
        private float shakeInterval;
        private float shakeRange;
        private Vector3 shakeOffset;
        
        private void UpdateShake()
        {
            if (MarchHudLod0==null)
            {
                return;
            }
            var ct = TimeUtils.GetClientTickTime();
            if (shakeStartTime != 0)
            {
                if (ct - shakeStartTime >= shakeDuration)
                {
                    shakeStartTime = 0;
                    shakeCdTime = 0;
                    shakeOffset = Vector3.zero;
                    if (IsShowBattleStyleHud())
                    {
                        if (commanderHead!=null)
                        {
                            commanderHead.transform.position = shakeBeforePos;
                        }
                    }
                    else
                    {
                        Vector3 localPosition;
                        //防守状态时 角色头像需要在城的中间
                        if (IsBattleInCenterType())
                        {
                            localPosition = BattleFormationHelper.cityDefenceHudOffset;
                        }
                        else if (MarchType == MarchType.COLLECT_3)
                        {
                            localPosition = BattleFormationHelper.cityDefenceHudOffset;
                        }
                        else
                        {
                            localPosition = BattleUtils.SpreadPosition;
                        }
                        if (commanderHead)
                        {
                            commanderHead.transform.localPosition = localPosition;
                        }
                    }
                }
                else
                {
                    if (ct >= shakeCdTime)
                    {
                        float xOffset = UnityEngine.Random.Range(-1f, 1f) * shakeRange;
                        float yOffset = UnityEngine.Random.Range(-1f, 1f) * shakeRange;
                        shakeOffset = new Vector3(xOffset,yOffset,0);
                        shakeCdTime = ct + shakeInterval;
                        if (commanderHead)
                        {
                            commanderHead.transform.position = commanderHead.transform.position + shakeOffset;
                        }
                    }

                }
            }
        }

        private Vector3 shakeBeforePos;
        public void Shake()
        {
            if (MarchHudLod0!=null)
            {
                var isShowBattleStyleUI = IsShowBattleStyleHud();
                if (isShowBattleStyleUI || !isShowBattleStyleUI && IsBattleInCenterType())
                {
                    shakeDuration = 0.15f;
                    shakeStartTime = TimeUtils.GetClientTickTime();
                    shakeCdTime = 0;
                    shakeInterval = 0.03f;
                    shakeRange = 0.06f;
                    if (commanderHead)
                    {
                        shakeBeforePos = commanderHead.transform.position;
                    }
                    UpdateShake();
                }
            }
        }

        public void OnInspector()
        {
            #if UNITY_EDITOR
            UnityEditor.EditorGUILayout.LabelField("因素");
            foreach (var item in headFactorToShowMap)
            {
                UnityEditor.EditorGUILayout.LabelField(item.Key.ToString(), item.Value.value.ToString());
            }
            
            
            UnityEditor.EditorGUILayout.LabelField("结果");
            foreach (var item in headShowChangeActionMap)
            {
                UnityEditor.EditorGUILayout.LabelField(item.Key.ToString(), item.Value.value.ToString());
            }
            
            #endif
        }

        public bool IsSiegeMarch()
        {
            return TargetCoordinateType.SIEGE_MARCH_8 == MarchEntity.RtsServerInfo.Type;
        }

        #region 英雄头像改变阶段
        
        public void SetRageHeroChanged(bool status)
        {
            if (_heroIconList == null || _heroIconList.Length == 0)
            {
                Debug.LogWarning( " 英雄头像改变阶段 _heroIconList == null || _heroIconList.Length == 0");
                return;
            }
            //是visible的时候,强行检测以及赋下当前头像的值
            //怒气条变更时,变更一次头像
            string defaultIcon = _heroIconList[GetCurHeroIdx()];

            if (heroIcon != defaultIcon)
            {
                heroIcon = defaultIcon;
                if (commanderHead && commanderHead.MainCommander)
                {
                    var mainCommander = commanderHead.MainCommander;
                    mainCommander.SetHero(defaultIcon, true);
                }
            }
            SetCurHeroRageLimit();
        }
        /// <summary>
        /// 获取当前英雄的头像下标
        /// </summary>
        /// <returns></returns>
        public int GetCurHeroIdx()
        {
            if (GetHeadShowValue(EHeadShowChange.IsBattleState) 
                && GetHeadShowValue(EHeadShowChange.IsRageVisible))
            {
                if (MarchEntity.CurRageHeroIdx > 0)
                    return MarchEntity.CurRageHeroIdx;
            }

            return 0;
        }
        
        /// <summary>
        /// 设置当前英雄的怒气上限
        /// </summary>
        /// <returns></returns>
        public int SetCurHeroRageLimit()
        {
            if (GetHeadShowValue(EHeadShowChange.IsRageVisible))
            {
                commanderHead.HpAndRage.SetRageBarMaxLimit(MaxRage,MarchEntity.CurHeroRageMax);
            }

            return 0;
        }
        
        /// <summary>
        /// 怒气切换过程中的英雄头像变更
        /// 1. 怒气技能释放前计时2s ChangeRageStatus(true) - 这个阶段怒气槽不能变更
        /// 2. 怒气技能释放结束,进入头像切换阶段              - 走入这个函数,解锁怒气槽锁定,同时变更为当前的英雄头像
        ///     2.1 这个函数是从CommanderHead里的一个动画事件过来的,在那个动画第五帧有一个完全空白的阶段,在这个阶段切换头像
        /// </summary>
        public void SwitchRageHero()
        {
            if (commanderHead == null || commanderHead.HpAndRage == null)
            {
                return;
            }
            commanderHead.HpAndRage.ChangeRageStatus(false);
            //获取当前的显示对象
            int curHeroIdx = GetCurHeroIdx();
            if (curHeroIdx < 0 || (_heroIconList!=null && curHeroIdx >= _heroIconList.Length))
            {
                Debug.LogError("SwitchRageHero 英雄头像下标越界");
                return;
            }
            string defaultIcon = _heroIconList[curHeroIdx];

            if (heroIcon != defaultIcon)
            {
                heroIcon = defaultIcon;
                if (commanderHead && commanderHead.MainCommander)
                {
                    var mainCommander = commanderHead.MainCommander;
                    mainCommander.SetHero(defaultIcon, true);
                }
            }
            SetCurHeroRageLimit();
        }
        
        #endregion
    }
}
